<?php
/**
 * Decypt a php file encryptd by KODExplorer
 * @author  langcai1943
 * @mail    zhangjing1943@163.com
 */

    /* Decrypt a function string, copy from encrypt file header. */
    function _kstr2($zym_var_42)
    {
        $zym_var_41 = strlen($zym_var_42);
        $zym_var_43 = '';
        $zym_var_44 = ord($zym_var_42[0]) - 30;
        for ($zym_var_46 = 1; $zym_var_46 < $zym_var_41; $zym_var_46 += 2)
        {
            if ($zym_var_46 + 1 < $zym_var_41)
            {
                $zym_var_43 .= chr(ord($zym_var_42[$zym_var_46 + 1]) + $zym_var_44);
                $zym_var_43 .= chr(ord($zym_var_42[$zym_var_46]) + $zym_var_44);
            }
            else
            {
                $zym_var_43 .= chr(ord($zym_var_42[$zym_var_46]) + $zym_var_44);
            }
        }
        return $zym_var_43;
    }

    /* Decrypt the kstr function of encrypted file. */
    function decrypt_kstr($contents)
    {
        /* 1. 从加密文件中找出所有要解码的函数字符串，存放在队列中。 */
            /* 要匹配的正则表达式，/是表达式前后边界符，([\s\S]*?)是匹配任意
               字符串，但尽可能短的匹配, \是转义字符，()是顺便获取子串 */
        $regexstr = "/_kstr2\('([\s\S]*?)'\)/";

            /* $matches是接收匹配结果的Array, 当前是返回一个二维数组，
               matches[0][0]是第一个匹配到的_kstr2('*')，
               matches[0][1]是第二个匹配到的_kstr2('*')，依次类推...
               matches[1][0]是第一次匹配到的字符串中的'*'单引号中的子字符串
               #（实际上我写的这个正则表达式是要匹配一个_kstr2方程的，但是
               不知道为什么连方程的参数也匹配到了，我很惊喜，然后发现小括号
               ()还可以返回它最后匹配的那个值）
               #注意！如果原文件中有\，则从文件中读出的字符串中为了显示正常，会
               将其替换为\\，但是你echo字符串却还是只能看到一个 */
        $times = preg_match_all($regexstr, $contents, $matches); /* preg_match_all
                会匹配所有的子串放到返回的数组中*/
        echo('times:'); var_dump($times);
 
            /* 如果var_dump打印出的东西没有换行和缩进，那么需要设置Xdebug，
               或者不想配环境的话在var_dump前面echo('<pre>'); 后面加上
               echo('<\pre>');即可。*/
        echo('find:<pre>');
///        var_dump($matches);
        echo('</pre>');

        /* 2. 将源文件中需要解密的字符串用解密后的字符串进行替换。 */
        for ($i=0; $i<$times; $i++) {
            $input = $matches[1][$i];
///            print_r('in: '.$input.'<br>');

                /* 解密时将正则表达式中为了正常显示用的\\替换为原来的\ */
            $input = str_replace('\\\\', '\\', $input);
            $decryptstr = _kstr2($input); /* 调用解密函数 */
///            print_r('out: '.$decryptstr.'<br>');

            $replacestr = '"'.$decryptstr.'"'; /* 将字符串用引号括起来 */
                /* 用明文替换加密的字符串 */
            $contents = str_replace($matches[0][$i], $replacestr, $contents);
//            print_r('encrypt: '.$contents.'<br>');
            
        }
//        echo('output:'.$contents);
        return $contents;
    }

    /* Decrypt the hex string of encrypted file. */
    function decrypt_hex($contents)
    {
//        echo 'param:'.$contents.'<br>';
        /* 1. 从加密文件中找出所有要反转译十六进制字符串，存放在队列中。 */
            /* 要匹配的正则表达式，/是表达式前后边界符，[0-9a-fA-F]{2}是匹配两位
               十六进制字符，+?是至少有一次但尽可能短的匹配, \是转义字符 */
            /* 因为将php文件读取到变量中时，源文件的一个\会替换成\\，
               虽然目标字符串显示时只会有一个\，但实际上要匹配两个\\ */
        $regexstr = '/"(\\\\x[0-9a-fA-F]{2})+?"/';

            /* $matches是接收匹配结果的Array, 当前是返回一个二维数组，
               matches[0][0]是第一个匹配到的"\x6a\x6b..."，
               matches[0][1]是第二个匹配到的"\x6c\x6d..."，依次类推...
               matches[1][0]是第一次匹配到的字符串中最后一个数\x6b */
        $times = preg_match_all($regexstr, $contents, $matches); /* preg_match_all
                会匹配所有的子串放到返回的数组中*/
        echo('times:'); var_dump($times);
 
            /* 如果var_dump打印出的东西没有换行和缩进，那么需要设置Xdebug，
               或者不想配环境的话在var_dump前面echo('<pre>'); 后面加上
               echo('<\pre>');即可。*/
        echo('<br>find:<pre>');
///        var_dump($matches);
        echo('</pre>');

        /* 2. 将源文件中需要反转译的字符串用反转译后的字符串进行替换。 */
        for ($i=0; $i<$times; $i++) {
            $input = $matches[0][$i];
///            print_r('in: ');
///            var_dump($input);
///            print_r('<br>');
                /* 解密时将正则表达式中为了正常显示用的\\替换为原来的\ */
            $input = stripcslashes($input); /* 将转译的字符串转成原字符串 */
///            print_r('out: '.$input.'<br>');

                /* 用反转译的字符串替换转译过的字符串 */
            $contents = str_replace($matches[0][$i], $input, $contents);
//            print_r('encrypt: '.$contents.'<br>');       
        }
///        echo('output:'.$contents);
        
        return $contents;
    }

    /* Decrypt the octonary string of encrypted file. */
    function decrypt_oct($contents)
    {
///        echo 'param:'.$contents.'<br>';
        /* 1. 从加密文件中找出所有要反转译道八进制字符串，存放在队列中。 */
            /* 要匹配的正则表达式，/是表达式前后边界符，[0-7]{3}是匹配三位
               八进制字符，+?是至少有一次但尽可能短的匹配, \是转义字符 */
            /* 因为将php文件读取到变量中时，源文件的一个\会替换成\\，
               虽然目标字符串显示时只会有一个\，但实际上要匹配两个\\ */
        $regexstr = '/"(\\\\[0-7]{3})+?"/';

            /* $matches是接收匹配结果的Array, 当前是返回一个二维数组，
               matches[0][0]是第一个匹配到的"\152\153..."，
               matches[0][1]是第二个匹配到的"\154\155..."，依次类推...
               matches[1][0]是第一次匹配到的字符串中最后一个数\153 */
        $times = preg_match_all($regexstr, $contents, $matches); /* preg_match_all
                会匹配所有的子串放到返回的数组中*/
        echo('times:'); var_dump($times);
 
            /* 如果var_dump打印出的东西没有换行和缩进，那么需要设置Xdebug，
               或者不想配环境的话在var_dump前面echo('<pre>'); 后面加上
               echo('<\pre>');即可。*/
        echo('<br>find:<pre>');
///        var_dump($matches);
        echo('</pre>');

        /* 2. 将源文件中需要反转译的字符串用反转译后的字符串进行替换。 */
        for ($i=0; $i<$times; $i++) {
            $input = $matches[0][$i];
///            print_r('in: ');
///            var_dump($input);
///            print_r('<br>');
                /* 解密时将正则表达式中为了正常显示用的\\替换为原来的\ */
            $input = stripcslashes($input); /* 将转译字符串转成原字符串 */
///            print_r('out: '.$input.'<br>');

                /* 用反转译的字符串替换转译过的字符串 */
            $contents = str_replace($matches[0][$i], $input, $contents);
//            print_r('encrypt: '.$contents.'<br>');       
        }
///        echo('output:'.$contents);
        
        return $contents;
    }

    echo('Enter decrypt application.<br>');

    /**** Get an encrypt file. ****/
    //$filename = "testEncryptText";
    $filename = "encryptPie.php";
//    var_dump(file_exists($filename));

    /**** Open file. ****/
    $handle = fopen($filename, "r");
    $len = filesize($filename);
    $contents = fread($handle, $len);
    echo '<br>len:'.$len.'<br>';

    /**** Decrypt the kstr function of file. ****/
    $retstr1 = decrypt_kstr($contents);
///    echo('output: '.$retstr1.'<br>');

    /**** Decrypt the hex string of file. ****/
    $retstr2 = decrypt_hex($retstr1);
    
    /**** Decrypt the octonary string of file. ****/
    $retstr3 = decrypt_oct($retstr2);
    fclose($handle);

    /**** Storage decrypt file ****/
    $wfilename = "/var/www/html/outputDecryptText";
    $handle = fopen($wfilename, "w+") or die("Cannot create file!");
    fwrite($handle, $retstr3);
    fclose($handle);
    echo 'Write file:'.$wfilename.'OK!<br>'
?>
